﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Douban.Modules.Info.ViewModels;
using Microsoft.Practices.Composite.Regions;
using Douban.Api;
using Microsoft.Practices.ServiceLocation;
using Douban.Core;
using Douban.Modules.Info.Views;
using System.Threading;
using System.ComponentModel;
using Douban.Api.User;
using System.Diagnostics;
using Douban.Api.Broadcast;
using System.Windows.Threading;

namespace Douban.Modules.Info
{
    public class InfoController
    {
        private const double RefreshInterval = 2.0;
        private const int UserRefreshWeight = 4;
        private int count = 0;
        private DoubanService _doubanService;
        private DispatcherTimer _timer;
        private IDictionary<string, IUserInfoViewModel> _userInfoViewModelCache;

        public InfoController(DoubanService doubanService)
        {
            _userInfoViewModelCache = new Dictionary<string, IUserInfoViewModel>();
            _doubanService = doubanService;
            SetRefreshTimer();
        }

        public void CheckInfo()
        {
            CheckInfo(_doubanService.UserService.CurrentUser.Id);
        }

        public void CheckInfo(string userId)
        {
            IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
            IRegion region = regionManager.Regions[RegionNames.MainRegion];

            IUserInfoViewModel vm;
            if (!_userInfoViewModelCache.TryGetValue(userId, out vm))
            {
                vm = ServiceLocator.Current.GetInstance<IUserInfoViewModel>();

                BackgroundWorker bgWorker = new BackgroundWorker();
                bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                bgWorker.RunWorkerCompleted += (sender, e) =>
                {
                    object[] result = (object[])e.Result;
                    vm.User = (UserDetail)result[0];
                    vm.Miniblog = (Miniblog)result[1];
                    _userInfoViewModelCache.Add(userId, vm);
                };
                bgWorker.RunWorkerAsync(userId);
                region.Add(vm.View);
            }

            region.Activate(vm.View);
        }

        private void SetRefreshTimer()
        {
            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMinutes(RefreshInterval);
            _timer.Tick += new EventHandler(_timer_Tick);
            _timer.Start();
        }

        private void _timer_Tick(object sender, EventArgs e)
        {
            try
            {
                foreach (var pair in _userInfoViewModelCache)
                {
                    string userId = pair.Key;
                    IUserInfoViewModel vm = pair.Value;

                    if (++count % UserRefreshWeight == 0)
                        vm.User = _doubanService.UserService.GetUserDetail(userId);

                    vm.Miniblog = _doubanService.BroadcastService.GetMiniblogs(userId, 1, 1).Miniblogs.FirstOrDefault();
                }
            }
            catch (Exception ex)
            { }
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string userId = (string)e.Argument;
            e.Result = new object[] 
            {
                _doubanService.UserService.GetUserDetail(userId),
                _doubanService.BroadcastService.GetMiniblogs(userId, 1, 1).Miniblogs.FirstOrDefault()
            };
        }
    }
}
